
public class Macierz {
	public int[][] tab;
	public String typ;
	public Cykle[] cykle;
	public Cykle[] pelne = new Cykle[50];
	public Cykle[] przepelnione;
	public String[] zbieracz;// = new Wezel[vertexTab.length+1][30];
	public Wezel[] vertexTab;
	public int g = 0;
	public Macierz() {
		//tab= new int[][]{{0,1,0,1,0,0},{1,0,1,1,1,0},{0,1,0,0,1,0},{1,1,0,0,0,1},{0,1,1,0,0,1},{0,0,0,1,1,0}};
		/*tab= new int[][]{{0,1,0,0,0,0,0,1},
				{1,0,1,0,0,0,0,1},
				{0,1,0,1,0,0,0,0},
				{0,0,1,0,1,0,1,0},
				{0,0,0,1,0,1,0,0},
				{0,0,0,0,1,0,1,0},
				{0,0,0,1,0,1,0,1},
				{1,1,0,0,0,0,1,0},
				};*/
		tab= new int[][]{{0,1,0,0,0,1,0},
				{1,0,1,0,1,1,0},
				{0,1,0,1,1,0,0},
				{0,0,1,0,1,0,1},
				{0,1,1,1,0,1,1},
				{1,1,0,0,1,0,1},
				{0,0,0,1,1,1,0}
				};
		/*tab= new int[][]{{0,1,0,1,1},
						 {1,0,1,0,1},
						 {0,1,0,1,1},
						 {1,0,1,0,1},
						 {1,1,1,1,0}
				};*/
		this.budujMacierz();
		this.cykl2(vertexTab[0]);
		this.rebuild();
		//traceCykle();
		
		//tracePelne();
		//traceTab(toDual());
		Mapa mapa = new Mapa(toDual());
		
		
	}
	public void traceTab(int[][] tablica) {
		
			for(int i=0; i<tablica.length; i++){
				for(int j=0; j<tablica[i].length; j++){
					System.out.print(tablica[i][j]+" ");
				
			}
				System.out.println();
		}
		
	}
	public String toString2(Wezel[] param) {
		String pomoc = new String();
		
		for(int i=0; i<param.length; i++){
			if(param[i]!=null) {
				
			
			pomoc+="-" + param[i].numer;
			}
		}
		
	return pomoc;
	}
	
	
	public int[][] toDual() {
		int z=0;
		
		for(int i=0; i<pelne.length; i++) {
			if(pelne[i]!=null&&pelne[i].kolumna.length>1) {
				z++;
			}
		}
		Cykle[] pomoc = new Cykle[z];
		z=0;
		for(int i=0; i<pelne.length; i++) {
			if(pelne[i]!=null&&pelne[i].kolumna.length>1) {
				pomoc[z] = pelne[i];
				z++;
			}
		}
		int[][] tabDual= new int[z][z];
		for(int i=0; i<pomoc.length; i++) {
		
			for(int j=0; j<pomoc.length; j++) {
				tabDual[i][j] = 0;
				if(i!=j) {
					
					if(czWspolna(pomoc[i].kolumna, pomoc[j].kolumna)>1) {
					
						tabDual[i][j] = 1;
					}
				}
				
			}
		}
		
		return tabDual;
	}
	public int czWspolna(Wezel[] param1, Wezel[] param2) {
		int test = 0;
		for(int i=0; i<param1.length; i++) {
			for(int j=0; j<param2.length; j++) {
				if(param1[i].numer == param2[j].numer) {
				
					test++;
					j=param2.length;
				}
			}
		}
		return test;
		
	}
	
	public void cykl2(Wezel start) {
		g=0;
		cykle = new Cykle[vertexTab.length * vertexTab.length* vertexTab.length];
		
		for(int i=0; i<start.rozmiar; i++) {
			krok3(start,start.support[i], start, new String(start.numer+"-"), new Wezel[]{start});
		}
		
	}

public void krok3(Wezel start,Wezel wezel, Wezel pochodzenie,String geneza,Wezel[] odwiedzone) {
	Boolean czysty=true;
		
		if(wezel!=null){//(vertexTab.length)*2) {
			Wezel[] pomoc = new Wezel[odwiedzone.length+1];
			Wezel[] pomoc2 = new Wezel[1];
			Boolean koniec = false;
			int j=0;
			int poczatek = 0;
		for(int i=0; i<odwiedzone.length; i++) {
			if(odwiedzone[i]==wezel) {
				poczatek=i;
				
				pomoc2 = null;
				pomoc2 = new Wezel[odwiedzone.length-i];
			koniec=true;
				
			}
			if(koniec==false) {
			pomoc[i] = odwiedzone[i];
			}
			
			if(koniec==true) {
			pomoc2[j] = odwiedzone[poczatek+j];
					j++;
			}
		}
			
			
		
		if(pochodzenie!=null&&koniec==false) {
			
		pomoc[odwiedzone.length] = wezel;
				
		for(int i=0; i<wezel.rozmiar; i++) {
			if(wezel.support[i]!=pochodzenie) {
				krok3(start,wezel.support[i], wezel, geneza+wezel.numer+"-", pomoc);
			}
		}
			} else {
				
			
				
				
				
				for(int i=0; i<g-1; i++) {
					if(cykle[i]!=null&&pomoc2!=null) {
						if(cykle[i].kolumna!=null&&toSamo(cykle[i].kolumna,pomoc2)) {
							czysty=false;
						
						}
						}
				}
				}
		if(czysty==true) {
		cykle[g] = new Cykle();
		cykle[g].kolumna = pomoc2;
				g++;
		}
					
				}
		
				//System.out.println();
			
		}
		
		
		

	public Boolean packed(Wezel[] podstawa, Wezel[] reszta) {
		System.out.println("---------------");
		toString2(podstawa);
		System.out.println();
		System.out.println("z");
		toString2(reszta);
		System.out.println();
		System.out.println("---------------");
		for(int i=0; i<podstawa.length; i++) {
			int test = reszta.length;
			for(int j=0; j<reszta.length; j++) {
				
				if(podstawa[i]!=null&&reszta[j]!=null&&podstawa[i].numer==reszta[j].numer) {
					//System.out.print(podstawa[i].numer + " z " + reszta[j].numer);
					test--;
				}
				if(test<=3) {
					
					return true;
				}
			}
			System.out.println(test);
			//System.out.println();
			
			
		}
		return false;
	}
	
		public void rebuild() {
			int z=0;
			Boolean packedC = false;
			for(int i=0; i<cykle.length; i++) {
				if(cykle[i]!=null&&cykle[i].kolumna!=null&&cykle[i].kolumna.length!=0) {
				for(int j=0; j<cykle.length; j++) {
					
					if(cykle[j]!=null&&cykle[j].kolumna!=null&&cykle[j].kolumna.length!=0) {
						
					if(i!=j&&cykle[j].kolumna.length > cykle[i].kolumna.length&&cykle[i]!=null) {
						if(packed2(toString2(cykle[j].kolumna), toString2(cykle[i].kolumna))) {
							//System.out.println(toString2(cykle[j].kolumna));
							//System.out.println(toString2(cykle[i].kolumna));
							//pelne[z] = new Wezel[]
							packedC = true;
							//pelne[z] = cykle[i];
							cykle[j] = null;
							z++;
							//System.out.println("aaaa");
							//j = g;
							//System.out.println(toString2(cykle[i].kolumna));
							
						}
				}
					}
				}
				if(packedC) {
					
				}
				}
			}
			pelne = new Cykle[g];
			for(int i=0; i<cykle.length; i++) {
				if(cykle[i]!=null&&cykle[i].kolumna!=null&&toString2(cykle[i].kolumna).length()>2) {
					pelne[i] = cykle[i];
					//System.out.println(toString2(cykle[i].kolumna));
				
				}
				
				
			}
			
			
		}
	
	public int indexOf(Cykle[] param1, Wezel[] cykl) {
		for(int i=0; i<param1.length; i++) {
			if(param1!=null&&param1[i]!=null&&param1[i].kolumna.length>0&&toSamo(param1[i].kolumna, cykl)) {
				//i = param1.length;
				
				return i;
				
			}
		}
		return -1;
	}
	public void traceCykle() {
		for(int i=0; i<g-1; i++) {
			Boolean cykl = false;
			if(cykle[i]!=null&&cykle[i].kolumna!=null&&cykle[i].kolumna.length!=0) {
				
			for(int j=0; j<cykle[i].kolumna.length; j++) {
				if(cykle[i].kolumna[j]!=null) {
					cykl=true;
				System.out.print(cykle[i].kolumna[j].numer + "-");
				}
			}
			if(cykl==true) {
			System.out.println();
			}
		}
		}
		
	}
	public void tracePelne() {
		for(int i=0; i<pelne.length; i++) {
			Boolean cykl = false;
			if(pelne[i]!=null&&pelne[i].kolumna!=null) {
			for(int j=0; j<pelne[i].kolumna.length; j++) {
				if(pelne[i].kolumna[j]!=null) {
					cykl=true;
				System.out.print(pelne[i].kolumna[j].numer + "-");
				}
			}
			if(cykl==true) {
				System.out.println();
				}
		}
		}
		
	}

	public Boolean toSamo(Wezel[] param1, Wezel[] param2) {
	
		if(param1.length==param2.length) {
			Boolean popr = false;
			
			int test = param1.length;
			for(int i=0; i<param1.length; i++) {
				
				for(int j=0; j<param2.length; j++) {
					
					if(param1[i]!=null&&param2[j]!=null) {
						
					if(param1[i].numer==param2[j].numer) {
						test--;
					}
					if(test==0) {
					
						popr=true;
					}
				}
					
				}
			}
				if(test==0) {
					
					popr=true;
				
			}
			return popr;
		}
		else {
			return false;
		}
		
	}
	public Boolean packed2(String param1, String param2) {
		Boolean zwrot = false;
		if(param1.length()>2&&param2.length()>2) {
		 zwrot = true;
		
		for(int i=0; i<param2.length(); i++){
			if(param1.indexOf(param2.charAt(i))==-1) {
				zwrot = false;
			}
		}
		}
		return zwrot;
		
	}
	
	public void powiazania() {
		for(int i=0; i<vertexTab.length; i++){
			
			System.out.println("/////////////////");
			System.out.println("Wezel numer: " + (vertexTab[i].numer+1));	
			System.out.println("Laczy sie z: " + vertexTab[i].toString());
			System.out.println("/////////////////");
		}
		
		
	}
	public void budujMacierz() {
		vertexTab = new Wezel[tab.length];
		for(int i=0; i<tab.length; i++){
			vertexTab[i] = new Wezel(i, tab.length);
		}
		
		
		for(int i=0; i<vertexTab.length; i++){
			for(int j=0; j<tab[i].length; j++) {
				if(tab[i][j] == 1) {
					//System.out.println(i + " laczy sie z " + j);
					int pomoc = vertexTab[i].rozmiar;
				vertexTab[i].support[pomoc] = vertexTab[j];
				vertexTab[i].rozmiar++;
				//System.out.println(i + " laczy sie z " + vertexTab[i].support[pomoc].numer);
				//System.out.println(pomoc);
				}
			}
		}
		
	}
}
